package com.leadership.api.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.utils.DateFormatUtils;
import com.demo2do.core.utils.DateUtils;
import com.demo2do.core.utils.StringUtils;
import com.leadership.api.dao.ActionLearningDao;
import com.leadership.api.dao.NotificationDao;
import com.leadership.api.handler.MailHandler;
import com.leadership.api.service.NotificationService;
import com.leadership.entity.Notification;
import com.leadership.entity.NotificationTemplate;
import com.leadership.entity.NotificationType;
import com.leadership.entity.actionlearning.ActionLearning;
import com.leadership.entity.actionlearning.Status;
import com.leadership.entity.project.LdProject;
import com.leadership.entity.user.Principal;
import com.leadership.entity.user.User;

/**
 * 
 * @author dan
 *
 */
@Service("notificationService")
public class NotificationServiceImpl implements NotificationService{
    
    private static final Logger logger = LoggerFactory.getLogger(NotificationServiceImpl.class);
    
    @Dao
    private NotificationDao notificationDao;
    
    @Dao
    private ActionLearningDao actionLearningDao;
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    @Autowired
    private MailHandler mailHandler;
    
    @Value("#{config['system.host']}")
    private String host;

    /*
     * (non-Javadoc)
     * @see com.leadership.scheduler.service.NotificationService#sendNotificationMail()
     */
    public void sendNotificationMail() {
        // list all unSended notification
        List<Notification> notifications = notificationDao.list(false);
        
        if(notifications.isEmpty()) {
            logger.trace("#sendNotificationMail() - the notification is empty");
            return;
        }
        
        // send email
        for(Notification notification : notifications) {
            
            // load user and actionLearning
            User user = genericDaoSupport.load(User.class, notification.getUserId());
            ActionLearning actionLearning = null;
            if(notification.getActionLearningId() != null) {
                actionLearning = genericDaoSupport.load(ActionLearning.class, notification.getActionLearningId());
            }
            
            LdProject project = genericDaoSupport.load(LdProject.class, user.getCurrentProjectId());
            Principal operator = genericDaoSupport.load(Principal.class, project.getOperator());
            
            // prepare text
            String text = null;
//            if(notification.getTemplate().getType().isUserCreate()) {
//                text = this.prepareUserCreate(user, notification);
//            } else 
            if(notification.getTemplate().getType().isLearningCreate()) {
                String url = host + "/action-learnings/" + actionLearning.getId() + "/reporter-view";
                text = this.prepareMessage(user, actionLearning, notification, operator, url);
            } else if (notification.getTemplate().getType().isMonthlyLearning()) {
                String url = host + "/action-learnings/" + actionLearning.getId();
                text = this.prepareMessage(user, actionLearning, notification, operator, url);
            }else if(notification.getTemplate().getType().isCreateLearningComment()) {
                String url = host + "/action-learnings/" + actionLearning.getId() + "/reporter-view";
                text = this.prepareMessage(user, actionLearning, notification, operator, url);
            }
            
            String title = org.apache.commons.lang3.StringUtils.replace(notification.getTemplate().getTitle(), "#username", user.getUsername());
            mailHandler.sendEmail(notification.getEmail(), title, text);
            
            // update notificateion
            genericDaoSupport.update(notification.send());
        }
        
    }

    /*
     * (non-Javadoc)
     * @see com.leadership.api.service.NotificationService#createMonthlyNotification(java.util.Date)
     */
    public void createMonthlyNotification(Date day) {
        // list all progressing action learning
        List<ActionLearning> actionLearnings = actionLearningDao.list(Status.PROCESSING);
        if(actionLearnings.isEmpty()) {
            logger.trace("#sendMonthlyMail the actionLearning is empty");
            return;
        }
        
        for(ActionLearning actionLearning : actionLearnings) {
            Date startDate = actionLearning.getStartDate();
            Date endDate = actionLearning.getEndDate();
            
            // 如果当前日期小于结束日期，当前日期距离开始日期正好是整月，发送邮件
            int days = DateUtils.daysBetween(startDate, day);
            if(!day.after(endDate) && days%30 == 0) {
                // create notification
                NotificationTemplate template = notificationDao.loadTemplate(NotificationType.MONTHLY_LERNING);
                Notification notification = new Notification(template, actionLearning.getUser().getEmail(), actionLearning.getUser().getId(), actionLearning.getId());
                genericDaoSupport.save(notification);
            }
        }
        
    }
    
    /**
     * 
     * @param user
     * @param actionLearning
     * @param notification
     * @param operator
     * @param url
     * @return
     */
    private String prepareMessage(User user, ActionLearning actionLearning, Notification notification, Principal operator, String url) {
        Map<String, String> models = new HashMap<String, String>();
        
        models.put("reporter", user.getReporter().getUsercn());
        models.put("username", user.getUsercn());
        models.put("competency", actionLearning.getCompetency().getName());
        models.put("endDate", DateFormatUtils.format(actionLearning.getEndDate(), "yyyy年MM月dd日"));
        models.put("operator", operator.getName());
        models.put("operatorEmail", operator.getEmail());
        models.put("url", url);
        models.put("sendDate", DateFormatUtils.format(new Date(), "yyyy年MM月dd日"));
        
        String text = this.prepareText(notification.getDescription(), models);
        return text;
    }
    
    /**
     * 
     * @param template
     * @param models
     * @return
     */
    protected String prepareText(String template, Map<String, String> models) {
        return StringUtils.replacePlaceHolder(template, models);
    }

}
